---@coding utf8

---@class CoContext
---@field context_id integer  # 上下文ID
---@field co thread           # 原生协程对象
---@field expire_ms  integer  # 超时时间
---@field user_data  table    # 自定义数据

---@type table<integer, CoContext>
co_context_map = {}    --- 只有
---TODO 增加thread到id的映射，用来检查是否会有多个多个id对应不同的thread

---@type integer
co_context_id_seed = 10000

---TODO: idle_coroutines 协程执行结束后不退出，放到这里等待复用

---@brief 生成新的上下文id
---@return integer
function co_make_context_id()
    repeat
        co_context_id_seed = co_context_id_seed + 1
        if co_context_id_seed > 0x7fffffffffffff then
            co_context_id_seed = 1
        end
    until not co_context_id_seed[co_context_id_seed]
    return co_context_id_seed
end

---@param fun fun(...)
function co_create(fun, ...)
    local co = coroutine.create(
        function (...)
            local ok, err_or_ret = xpcall(fun, debug.traceback, ...)
        end
    )
    return co
end

---@param fun fun(...)
function co_start(fun, ...)
    local co = co_create(fun, ...)
    coroutine.resume(co, ...)
end

---@brief 不能被直接调用，否则无法保证co_context_map中的协程全都是休眠状态
---@param co thread
function co_resume(co, ...)
    coroutine.resume(co, ...)
end

function co_yield(timeout_ms, user_data)
    local co = coroutine.running()
    local context_id = co_make_context_id()
    co_context_map[context_id] = {
        context_id = context_id,
        co = co,
        user_data = user_data,
        expire_ms = math.ceil(os.clock()*1000) + timeout_ms,
    }
end

function co_sleep(ms)
    co_yield(ms, {})
end

---@brief
function helix_session_make_co_context_id(session_id, event)
end
---@type table<integer, table<string, integer>>
sid_wait_event_map = {}

---@brief 注册session等待信息到调度器
function reg_session_wait_context(session_id, event)
    local context_id = co_make_context_id()
    local event2context_id = sid_wait_event_map[session_id]

end


---@brief 唤醒helix-session上等待的协程
function helix_session_co_resume(session_id, event)

end


function helix_session_wait(session_id, event, timeout_ms)
    co_yield(timeout_ms, {session_id = session_id, event = event})
end

-- ss.connect()
-- ss.wait_connect_result()
-- ss.login()
-- ss.wait_rsp()
-- ss.sleep(1)
-- ss.xxxReq()
-- ss.wait_rsp(...)